package org.luxor.commons.storage.client.disk;

import org.apache.commons.io.IOUtils;
import org.luxor.commons.storage.client.AbstractStorageClient;
import org.luxor.commons.storage.client.AbstractStorageProperties;
import org.luxor.commons.storage.constant.StorageType;
import org.luxor.commons.storage.exception.FileNotFoundException;
import org.luxor.commons.storage.exception.StorageServiceException;
import org.luxor.commons.storage.exception.StorageTypeNotSupportedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * 本地磁盘存储
 *
 * @author Mr.yan @date 2019/12/15
 */
public class DiskStorageClient extends AbstractStorageClient {
    private static final Logger logger = LoggerFactory.getLogger(DiskStorageClient.class);

    private final DiskProperties properties;

    public DiskStorageClient(DiskProperties properties) {
        this.properties = properties;
        if (this.isEnabled()) {
            this.init();
        }
    }

    private void init() {
        logger.info("Initialization DiskStorage open ( Storage Directory Prepare)");
        try {
            String dataDir = properties.getDataDir();
            File dataDirFile = new File(dataDir);
            if (!dataDirFile.exists()) {
                dataDirFile.mkdirs();
            }
            logger.info("Initialize DiskStorage Success,bye");
        } catch (Throwable e) {
            logger.error("Initialize DiskStorage Failure!", e);
            throw e;
        }
    }

    @Override
    public AbstractStorageProperties getConfig() {
        return this.properties;
    }

    @Override
    public boolean isEnabled() {
        return this.properties.isEnabled();
    }

    @Override
    public String upload(byte[] fileByte, String fileName, String suffix) {
        if (!this.isEnabled()) {
            logger.error("[未开启] 本地磁盘文件存储功能.");
            throw new StorageTypeNotSupportedException("[未开启] 本地磁盘文件存储功能");
        }

        String fileFullPath = getFilePath(StorageType.DISK, properties.getDataDir(), fileName, suffix);
        logger.info("保存文件,路径:{}", fileFullPath);

        BufferedOutputStream fos = null;
        BufferedInputStream bis = null;
        try {
            File file = new File(fileFullPath);
            file.getParentFile().mkdirs();
            file.createNewFile();
            fos = new BufferedOutputStream(Files.newOutputStream(file.toPath()));
            bis = new BufferedInputStream(new ByteArrayInputStream(fileByte));
            int len;
            byte[] buf = new byte[2048];
            while ((len = bis.read(buf)) != -1) {
                fos.write(buf, 0, len);
            }
            fos.flush();
            return fileFullPath;
        } catch (IOException e) {
            logger.error("磁盘保存文件失败!", e);
            throw new StorageServiceException("磁盘保存文件失败!", e);
        } finally {
            IOUtils.closeQuietly(fos);
            IOUtils.closeQuietly(bis);
        }
    }

    @Override
    public byte[] download(String fileFullPath) {
        if (!this.isEnabled()) {
            logger.error("[未开启] 本地磁盘文件存储功能. fileFullPath:{}", fileFullPath);
            throw new StorageTypeNotSupportedException("[未开启] 本地磁盘文件存储功能");
        }
        logger.info("读取文件,路径:{}", fileFullPath);

        BufferedInputStream fis = null;
        ByteArrayOutputStream bos = null;
        try {
            fis = new BufferedInputStream(Files.newInputStream(Paths.get(fileFullPath)));
            bos = new ByteArrayOutputStream();
            int len;
            byte[] buf = new byte[2048];
            while ((len = fis.read(buf)) != -1) {
                bos.write(buf, 0, len);
            }
            bos.flush();
            return bos.toByteArray();
        } catch (FileNotFoundException e) {
            logger.error("文件不存在!", e);
            throw new FileNotFoundException("文件不存在!", e);
        } catch (IOException e) {
            logger.error("读取文件失败!", e);
            throw new StorageServiceException("读取文件失败!", e);
        } finally {
            IOUtils.closeQuietly(fis);
            IOUtils.closeQuietly(bos);
        }
    }

    @Override
    public void delete(String fileFullPath) {
        if (!this.isEnabled()) {
            logger.error("[未开启] 本地磁盘文件存储功能. fileFullPath:{}", fileFullPath);
            throw new StorageTypeNotSupportedException("[未开启] 本地磁盘文件存储功能");
        }
        logger.info("删除文件,路径:{}", fileFullPath);

        File delFile = new File(fileFullPath);
        if (delFile.exists()) {
            delFile.delete();
        }
    }

}
